﻿using System;
using OpenLS.Spreadsheet.Extensibility;

namespace OpenLS.Spreadsheet.AnalysisToolPak
{
    internal static class EuroHelper
    {
        private static double Truncate(double value)
        {
            return value >= 0 ? Math.Floor(value) : -Math.Floor(-value);
        }

        public static double EuroConvert(double Number, string Source, string Target, bool Full_Precision, int Triangulation_precision)
        {
            double c1 = new EuropeanCurrency(Source).EuroValue;
            var targetCurrency = new EuropeanCurrency(Target);
            double c2 = targetCurrency.EuroValue;

            if (c1 >= 0 && c2 >= 0)
            {
                double result = Number/c1;
                if (Full_Precision && Triangulation_precision != int.MinValue)
                {
                    int decimals = (Triangulation_precision);
                    if (decimals < 3 || decimals > 16384)
                        throw new ErrorException(Errors.ValueError);
                    else
                    {
                        double p10 = Math.Pow(10, decimals);
                        result = Truncate(result*p10 + 0.5)/p10;
                    }
                }
                result = result*c2;
                if (!Full_Precision)
                {
                    int decimals = targetCurrency.LocalRounding;
                    double p10 = Math.Pow(10, decimals);
                    result = Truncate(result*p10 + 0.5)/p10;
                }
                return result;
            }
            throw new ErrorException(Errors.ValueError);
        }

        #region Nested type: EuropeanCurrency

        private struct EuropeanCurrency
        {
            private readonly string _code;

            public EuropeanCurrency(string code)
            {
                _code = code;
            }

            public double EuroValue
            {
                get
                {
                    switch (_code)
                    {
                        case "ATS":
                            return (13.7603);
                        case "BEF":
                            return 40.3399;
                        case "CYP":
                            return 0.585274;
                        case "DEM":
                            return 1.95583;
                        case "ESP":
                            return 166.386;
                        case "EUR":
                            return 1.0;
                        case "FIM":
                            return 5.94573;
                        case "FRF":
                            return 6.55957;
                        case "GRD":
                            return 340.75;
                        case "IEP":
                            return 0.787564;
                        case "ITL":
                            return 1936.27;
                        case "LUF":
                            return 40.3399;
                        case "MTL":
                            return 0.429300;
                        case "NLG":
                            return 2.20371;
                        case "PTE":
                            return 200.482;
                        case "SIT":
                            return 239.640;
                        case "SKK":
                            return 30.1260;
                        default:
                            throw new NotSupportedException();
                    }
                }
            }

            public int LocalRounding
            {
                get
                {
                    switch (_code)
                    {
                        case "BEF":
                            return 0;
                        case "LUF":
                            return 0;
                        case "DEM":
                            return 2;
                        case "ESP":
                            return 0;
                        case "FRF":
                            return 2;
                        case "IEP":
                            return 2;
                        case "ITL":
                            return 0;
                        case "NLG":
                            return 2;
                        case "ATS":
                            return 2;
                        case "PTE":
                            return 0;
                        case "FIM":
                            return 2;
                        case "GRD":
                            return 0;
                        case "SIT":
                            return 2;
                        case "EUR":
                            return 2;
                    }
                    throw new NotSupportedException();
                }
            }
        }

        #endregion
    }
}